/*
 *  rlocuswidget.h
 *  Perceel
 *
 *  Created by Nicola Gigante on 24/03/08.
 *  Copyright 2008 Nicola Gigante. All rights reserved.
 *
 */

#ifndef __RLOCUSWIDGET_H__
#define __RLOCUSWIDGET_H__

#include <QApplication>
#include <QWidget>
#include <QMouseEvent>
#include <QPainter>
#include <QImage>
#include <QMatrix>
#include <QTimer>
#include <QTime>

#include "tf.h"

class PlotWidget : public QWidget
{
	Q_OBJECT
	
public:
	enum PointerMode
	{
		PointMode,
		DragMode
	};
	
private:
	
	TF m_tf;
	QPointF m_origin; // The position of the origin point in NON translated coordinates
	Real x_scale;
	Real y_scale;
	QImage rendering;
	QTimer resizeTimer;
	bool m_dragging;
	bool m_resizing;
	QPoint m_dragDistance;
	QPoint m_oldDrawPoint;
	QPoint m_drawPoint;
	bool initPlotDone;
	bool m_firstPaint;
	PointerMode m_pointerMode;
	
	Real m_horizAxis;   // Virtual position
	Real m_vertAxis;	// Virtual position
	
	QList<QPointF> m_points;
	
public:
	PlotWidget(QWidget *parent = 0);
	
	virtual TF tf() const { return m_tf; }
	virtual void setTF(const TF &tf) { m_tf = tf; reset(); }
	
	QPointF origin() const { return m_origin; }
	virtual void setOrigin(const QPointF &o);
	
	Real xScale() const { return x_scale; }
	Real yScale() const { return y_scale; }
	
	void setScale(Real x, Real y);
	void setXScale(Real x) { setScale(x, yScale()); }
	void setYScale(Real y) { setScale(xScale(), y); }
	
	PointerMode pointerMode() { return m_pointerMode; }
	void setPointerMode(PointerMode m);
	
	QImage doRendering(bool alone = false);
	
signals:
	void detailsChanged(const QMap<QString, QString> &details);
	
public slots:
	void resizingFinished();
	void zoomIn();
	void zoomOut();
	void reset();
	
protected:
	// To reimplement for subclassing
	virtual void initPlot(QPainter &painter) = 0;
	virtual void plot(QPainter &painter) = 0;
	virtual void guessScale() = 0;
	virtual QMap<QString, QString> pixelDetails(QPoint) { return QMap<QString, QString>(); }
	
	void invalidate();
	Real horizontalAxis() const { return m_horizAxis; }
	Real verticalAxis() const { return m_vertAxis; }
	void setHorizontalAxis(Real pos);
	void setVerticalAxis(Real pos);
	QPoint map(QPoint p);
	QPointF map(QPointF p);
	QPointF map(Complex c);
	Complex unMap(QPointF p);
	
	void drawAces(QPainter &painter);
	virtual void paintEvent(QPaintEvent *event);
	virtual void resizeEvent(QResizeEvent *event);
	virtual void mousePressEvent(QMouseEvent *event);
	virtual void mouseReleaseEvent(QMouseEvent *event);
	virtual void mouseMoveEvent(QMouseEvent *event);
};

#endif
